From c9c1967cb0d4646e70cb86387916b85520d16c5c Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Wed, 1 Mar 2006 14:49:31 +0100 Subject: [PATCH] Clean wrpt state when emulating CR3 write. Signed-off-by: Keir Fraser --- xen/arch/x86/mm.c | 14 ++++---------- xen/arch/x86/traps.c | 1 + xen/include/asm-x86/mm.h | 4 ++++ 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index 321d2b9dee..1e29ce5d2d 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -475,7 +475,8 @@ get_page_from_l1e( { MEM_LOG("Error getting mfn %lx (pfn %lx) from L1 entry %" PRIpte " for dom%d", - mfn, get_gpfn_from_mfn(mfn), l1e_get_intpte(l1e), d->domain_id); + mfn, get_gpfn_from_mfn(mfn), + l1e_get_intpte(l1e), d->domain_id); } return okay; @@ -515,7 +516,6 @@ get_page_from_l2e( #if CONFIG_PAGING_LEVELS >= 3 - static int get_page_from_l3e( l3_pgentry_t l3e, unsigned long pfn, @@ -545,11 +545,9 @@ get_page_from_l3e( #endif return rc; } - #endif /* 3 level */ #if CONFIG_PAGING_LEVELS >= 4 - static int get_page_from_l4e( l4_pgentry_t l4e, unsigned long pfn, @@ -579,7 +577,6 @@ get_page_from_l4e( return rc; } - #endif /* 4 level */ @@ -649,28 +646,23 @@ static void put_page_from_l2e(l2_pgentry_t l2e, unsigned long pfn) #if CONFIG_PAGING_LEVELS >= 3 - static void put_page_from_l3e(l3_pgentry_t l3e, unsigned long pfn) { if ( (l3e_get_flags(l3e) & _PAGE_PRESENT) && (l3e_get_pfn(l3e) != pfn) ) put_page_and_type(mfn_to_page(l3e_get_pfn(l3e))); } - #endif #if CONFIG_PAGING_LEVELS >= 4 - static void put_page_from_l4e(l4_pgentry_t l4e, unsigned long pfn) { if ( (l4e_get_flags(l4e) & _PAGE_PRESENT) && (l4e_get_pfn(l4e) != pfn) ) put_page_and_type(mfn_to_page(l4e_get_pfn(l4e))); } - #endif - static int alloc_l1_table(struct page_info *page) { struct domain *d = page_get_owner(page); @@ -1569,6 +1561,8 @@ int new_guest_cr3(unsigned long mfn) int okay; unsigned long old_base_mfn; + ASSERT(writable_pagetable_in_sync(d)); + if ( shadow_mode_refcounts(d) ) { okay = get_page_from_pagenr(mfn, d); diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index 2dabc44c31..97cf8bb5ab 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -951,6 +951,7 @@ static int emulate_privileged_op(struct cpu_user_regs *regs) case 3: /* Write CR3 */ LOCK_BIGLOCK(v->domain); + cleanup_writable_pagetable(v->domain); (void)new_guest_cr3(gmfn_to_mfn(v->domain, paddr_to_pfn(*reg))); UNLOCK_BIGLOCK(v->domain); break; diff --git a/xen/include/asm-x86/mm.h b/xen/include/asm-x86/mm.h index 4d7870fb03..040d919626 100644 --- a/xen/include/asm-x86/mm.h +++ b/xen/include/asm-x86/mm.h @@ -337,6 +337,10 @@ void cleanup_writable_pagetable(struct domain *d); UNLOCK_BIGLOCK(d); \ } while ( 0 ) +#define writable_pagetable_in_sync(d) \ + (!((d)->arch.ptwr[PTWR_PT_ACTIVE].l1va | \ + (d)->arch.ptwr[PTWR_PT_INACTIVE].l1va)) + int audit_adjust_pgtables(struct domain *d, int dir, int noisy); #ifndef NDEBUG -- 2.30.2